package game;

import java.util.List;

public class Player extends Entity {
    
    /** Default Player Velocity */
    public static final float DEFAULT_VELOCITY = 3F;

    /** How many frames a player wait before firing again */
    public static final int FIRING_COOLDOWN = 3;
    
    /** The number of frames since the player last fired */
    private int lastFired;
    //Tracks how recently player has hit a wall to prevent getting stuck
    private int lastHitWall;
    private boolean autoPilot;
    
    public int getLastHitWall() {
	return lastHitWall;
    }
    
    public Player(float x, float y) {
	this(x, y, new Boundary(0, 0, 400, 600));
    }
    
    public Player(float x, float y, Boundary bounds) {
	super(x, y, bounds);
    }

    @Override
    public void update() {
	if (!autoPilot) {
	    if (canMoveX()) {
		x+=velocity * Math.cos(angle);
	    }
	    if (canMoveY()) {
		y+=velocity * Math.sin(angle);
	    }
	} else {
	    if (canMove()) {
		lastHitWall++;
		x+=velocity * Math.cos(angle);
		y+=velocity * Math.sin(angle);
	    } else {
		lastHitWall = 0;
		//System.out.println("hitting wall");
		angle = bounds.getBounceAngle(canMoveX(), canMoveY(), angle);
	    }
	}
    }
    
    public void update(List<Bullet> enemyBullets) {
	Bullet closestBullet = null;
	if (!autoPilot) {
	    update();
	    return;
	}
	for(Bullet b:enemyBullets) {
	    if (closestBullet == null) {
		closestBullet = b;
	    } else {
		if (GameBoard.getDistanceSquared(this,b) < GameBoard.getDistanceSquared(this,closestBullet)) {
		    //System.out.println("Ousting " + GameBoard.getDistanceSquared(this,closestBullet) + "in favor of " + GameBoard.getDistanceSquared(this,b));
		    closestBullet = b;
		}
	    }
	}
	if (closestBullet == null) {
	    update();
	    return;
	}
	if (GameBoard.getDistanceSquared(this,closestBullet) < 700 && lastHitWall > 5) {  //run away from bullet
	    double slope;
	    double angle;
	    if (getX() - closestBullet.getX() == 0) {
		if (getY() < closestBullet.getY()) {
		    angle = Math.PI*3/2+.001; //trying to avoid getting stuck, that's why adding +.001
		} else {
		    angle = Math.PI/2+.001;
		}
	    } else {
		slope = ((double)getY() - closestBullet.getY()) / ((double)getX() - closestBullet.getX());
		angle = Math.atan(slope);
		if (getX() < closestBullet.getX()) {
		    angle = Math.PI + angle;
		}
	    }
	    this.angle = angle;
	    //this.angle+= Math.PI/2;
	}
	update();
    }
    
    public void setAutoPilot(boolean autoPilot) {
	this.autoPilot = autoPilot;
    }
    
    public boolean isAutoPilot() {
	return autoPilot;
    }
    
    public boolean canFire() {
	return (lastFired > FIRING_COOLDOWN);
    }
    
    public void updateLastFired(boolean justFired) {
	if (justFired) {
	    lastFired = 0;
	} else {
	    lastFired++;
	}
    }
    
    public int getCollisionRadius() {
	return 10;
    }
}
